package com.gzxx.service.impl;

import com.gzxx.constant.ServiceCodeStatus;
import com.gzxx.constant.SystemConstant;
import com.gzxx.domain.base.BaseVo;
import com.gzxx.domain.bo.SysDeptBO;
import com.gzxx.domain.po.SysDept;
import com.gzxx.domain.vo.SysDeptVo;
import com.gzxx.exception.ServiceException;
import com.gzxx.mapper.SysDeptMapper;
import com.gzxx.service.SysDeptService;
import com.gzxx.util.ServerResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * SysDeptService
 *
 * @author chenjing
 * @date 2020-09-22 17:43:19
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Transactional(readOnly = true, rollbackFor = Exception.class, timeout = 5)
public class SysDeptServiceImpl implements SysDeptService {

    private final SysDeptMapper sysDeptMapper;

    /**
     * 列表
     */
    @Override
    public List<SysDeptVo> list(SysDeptBO sysDeptBO) {
        try {
            Map<?, ?> queryParams = sysDeptBO.queryParams();
            return sysDeptMapper.queryList(queryParams);
        } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            throw new ServiceException("class:SysDeptServiceImpl method:list exception", e);
        }
    }

    /**
     * 详情
     */
    @Override
    public SysDeptVo getDetail(Long id) {
        SysDeptVo sysDept = sysDeptMapper.singleDetail(id);
        return sysDept;
    }

    /**
     * 新增
     */
    @Transactional(rollbackFor = Exception.class, timeout = 5)
    @Override
    public ServerResponse add(SysDeptBO sysDeptBO) {
        SysDeptVo sysDeptVo;
        if (SystemConstant.DeptLevel.FIRST.getLevel().equals(sysDeptBO.getLevel())) {
            sysDeptVo = sysDeptMapper.queryByName(sysDeptBO.getName());
        } else {
            sysDeptVo = sysDeptMapper.queryByNameAndParentId(sysDeptBO.getName(), sysDeptBO.getParentId());
        }
        if (!ObjectUtils.isEmpty(sysDeptVo)) {
            return ServerResponse.error("部门名称不可重复");
        }
        SysDept sysDept = sysDeptBO.persist();
        boolean result = sysDeptMapper.insert(sysDept) > 0;
        return result ? ServerResponse.success(ServiceCodeStatus.SUCCESS) : ServerResponse.error();
    }

    /**
     * 更新
     */
    @Transactional(rollbackFor = Exception.class, timeout = 5)
    @Override
    public ServerResponse update(SysDeptBO sysDeptBO) {
        SysDeptVo sysDeptVo = sysDeptMapper.singleDetail(sysDeptBO.getId());
        if (ObjectUtils.isEmpty(sysDeptVo)) {
            return ServerResponse.error("部门不存在");
        }
        SysDeptVo deptVo = sysDeptMapper.queryByNameAndParentId(sysDeptBO.getName(), sysDeptVo.getParentId());
        if (!ObjectUtils.isEmpty(deptVo) && !deptVo.getId().equals(sysDeptBO.getId())) {
            return ServerResponse.error("部门名称不可重复");
        }
        SysDept sysDept = sysDeptBO.edit();
        boolean result = sysDeptMapper.updateById(sysDept) > 0;
        return result ? ServerResponse.success(ServiceCodeStatus.SUCCESS) : ServerResponse.error();
    }

    /**
     * 变更状态
     */
    @Transactional(rollbackFor = Exception.class, timeout = 5)
    @Override
    public ServerResponse changeStatus(SysDeptBO sysDeptBO) {
        int num = sysDeptMapper.updateById(sysDeptBO.changeStatus());
        return num > 0 ? ServerResponse.success(ServiceCodeStatus.SUCCESS) : ServerResponse.error();
    }

    /**
     * 根据id批量获取
     */
    @Override
    public List<BaseVo> getBaseVoByIds(List<Long> ids) {
        return sysDeptMapper.queryIds(ids);
    }

    /**
     * 根据用户获取部门
     */
    @Override
    public List<SysDeptVo> getByUserId(Long userId) {
        List<SysDeptVo> list = sysDeptMapper.queryByUserId(userId);
        return list;
    }

    /**
     * 获取部门 树形
     */
    @Override
    public List<BaseVo> treeList() {
        List<BaseVo> baseVos = sysDeptMapper.queryAll();
        if (ObjectUtils.isEmpty(baseVos)) {
            return null;
        }
        // 一级菜单
        List<BaseVo> oneList = baseVos.stream().filter(item -> item.getParentId() == null || item.getParentId() == 0).collect(Collectors.toList());
        // 根据父id分组
        Map<Long, List<BaseVo>> mapByParentId = baseVos.stream().filter(item -> item.getParentId() != null && item.getParentId() > 0)
                .collect(Collectors.groupingBy(BaseVo::getParentId));
        // 不存在二级菜单直接返回空
        if (mapByParentId.isEmpty()) {
            return null;
        }
        int num = oneList.size() - 1;
        for (int i = num; i >= 0; i--) {
            Long id = oneList.get(i).getValue();
            // 不存在二级菜单则删除
            if (!mapByParentId.containsKey(id)) {
                oneList.remove(oneList.get(i));
                continue;
            }
            oneList.get(i).setChildren(mapByParentId.get(id));
        }
        return oneList;
    }
}

